package web.protocols.action;

import com.opensymphony.xwork2.ActionSupport;
import domain.entities.*;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import services.*;
import services.exceptions.NoProtocoloCompromisopaisSelectedException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: vgonzalez
 * Date: 21/09/12
 * Time: 11:59
 * To change this template use File | Settings | File Templates.
 */

@Namespace("/Protocols/CountryCommitment")
public class CountryCommitmentController extends ActionSupport {
    private ProtocolCRUDService protocolService;
    private ObjetivoService objetivoService;
    private EnrolledPatientsService enrolledPatientsService;
    private ProtocoloCompromisopaisService protocoloCompromisopaisService;
    //private ProtocoloCompromisopais protocoloCompr;
    private Protocolo protocoloRecovered;
    private List<Compromisopais> paisList;
    private Integer countryId;
    private ProtocoloCompromisopais protocoloAEditar;
    private List<ProtocoloCompromisopais> listaCargados;
    private Integer editPaisId;
    private Integer editGlobalId;
    private String editProtId;
    private List<Integer> yearList = new ArrayList<Integer>();
    private GlobalCommitment globalCommitment;
    private GlobalCommitment globalCommitmentForList;
    private GlobalCommitmentService globalCommitmentService;


    @Autowired
    public CountryCommitmentController(ProtocolCRUDService protocolService, ProtocoloCompromisopaisService protocoloCompromisopaisService, ObjetivoService objetivoService, EnrolledPatientsService enrolledPatientsService, GlobalCommitmentService globalCommitmentService){
        this.protocolService = protocolService;
        this.protocoloCompromisopaisService = protocoloCompromisopaisService;
        this.objetivoService = objetivoService;
        this.enrolledPatientsService = enrolledPatientsService;
        this.globalCommitmentService = globalCommitmentService;
        for (int i = 2010; i< 2040; i++)
            this.yearList.add(new Integer(i));
    }

    private String cargarProtActual(){
        try{
            //protocoloCompr = protocolService.recoverProtocoloCompromisopais();
            protocoloRecovered = protocolService.recoverProtocolo();
        }
        catch (NoProtocoloCompromisopaisSelectedException e){
            e.printStackTrace();
        }
        if(protocoloRecovered == null)
            return null;

        return SUCCESS;
    }

    private String cargarTablaYPaises(){
        this.paisList = protocoloCompromisopaisService.findCompromisoPaisByProtocoloId(protocoloRecovered.getId());
        globalCommitmentForList = globalCommitmentService.findByProtocoloId(protocoloRecovered.getId());
        if(globalCommitmentForList == null)
            paisList.add(new Compromisopais(-2,"Global"));

        listaCargados = protocoloCompromisopaisService.getWithDataForCommitment(protocoloRecovered.getId());
        Iterator<ProtocoloCompromisopais> it = listaCargados.iterator();
        while(it.hasNext()){
            ProtocoloCompromisopais actual = it.next();
            paisList.remove(actual.getCompromisopais());
        }
        return SUCCESS;
    }

    @Action(value="main", results={
            @Result(name="success", location="/protocols.commitment.tiles", type="tiles")
    })
    public String execute() {
        if(cargarProtActual() == null)
            return null;
        cargarTablaYPaises();
        return SUCCESS;
    }

    @Action(value="changeToGlobal", results={
            @Result(name="success", location="/protocols.commitment.tiles", type="tiles")
    })
    public String changeToGlobal(){
        if(cargarProtActual() == null)
            return null;
        cargarTablaYPaises();
        globalCommitment = new GlobalCommitment();
        protocoloAEditar = null;

        return SUCCESS;
    }

    @Action(value="edit", results={
            @Result(name="success", location="/protocols.commitment.tiles", type="tiles")
    })
    public String edit() {
        if(cargarProtActual() == null)
            return null;
        cargarTablaYPaises();
        if(editGlobalId != null){
            globalCommitment = globalCommitmentService.findById(editGlobalId);
            protocoloAEditar = null;
        }
        else{
            protocoloAEditar = protocoloCompromisopaisService.getByProtocoloIdCompromisopaisId(editProtId, editPaisId);
            if(protocoloAEditar != null && protocoloAEditar.getEnrolledPatients() != null){
                Collections.sort(protocoloAEditar.getEnrolledPatients());
            }
            globalCommitment = null;
        }
        return SUCCESS;
    }

    @Action(value="clean", results={
            @Result(name="success", location="/protocols.commitment.tiles", type="tiles")
    })
    public String clean() {
        if(cargarProtActual() == null)
            return null;

        cargarTablaYPaises();

        protocoloAEditar = null;
        globalCommitment = null;

        return SUCCESS;
    }

    @Action(value="save", results={
            @Result(name="success", location="/protocols.commitment.tiles", type="tiles")
    })
    public String save() {
        if(cargarProtActual() == null)
            return null;
        if(protocoloAEditar != null && protocoloAEditar.getCompromisopais() != null){
            protocoloAEditar.setProtocolo(protocoloRecovered);
            ProtocoloCompromisopais pcp = protocoloCompromisopaisService.getByProtocoloIdCompromisopaisId(protocoloRecovered.getId(),protocoloAEditar.getCompromisopais().getId());
            if(pcp == null ){
                ProtocoloCompromisopaisId id = new ProtocoloCompromisopaisId(protocoloRecovered.getId(), protocoloAEditar.getCompromisopais().getId());
                pcp.setId(id);
            }
            pcp.setPlannedFpfv(protocoloAEditar.getPlannedFpfv());
            pcp.setPlannedLpfv(protocoloAEditar.getPlannedLpfv());
            pcp.setPlannedLplv(protocoloAEditar.getPlannedLplv());

            pcp.setObjetivos(protocoloAEditar.getObjetivos());
            pcp.setEnrolledPatients(protocoloAEditar.getEnrolledPatients());

            int size = pcp.getObjetivos().size();
            ArrayList<Integer> toRemove = new ArrayList<Integer>();

            for(int index = 0; index < size; index++){
                Objetivo actual = pcp.getObjetivos().get(index);
                if(actual != null && actual.getFecha() != null && actual.getObjetivo() != null) {
                    actual.setProtocoloCompromisopais(pcp);
                    objetivoService.attachDirty(actual);
                }
                else{
                    toRemove.add(index);
                }
            }

            Iterator<Integer> itRemove = toRemove.iterator();
            int borrados = 0;
            while(itRemove.hasNext()){
                int indice = itRemove.next().intValue() - borrados;
                Integer id = pcp.getObjetivos().get(indice).getId();
                if (id != null){
                    Objetivo aBorrar = objetivoService.findById(id);
                    objetivoService.delete(aBorrar);
                }
                pcp.getObjetivos().remove(indice);
                borrados ++;
            }

            toRemove.clear();

            int orden = 1;
            size = pcp.getEnrolledPatients().size();
            for(int index = 0; index < size; index++){
                EnrolledPatients actual = pcp.getEnrolledPatients().get(index);
                if(actual != null && ( actual.getTargetEnrolledAmount() != null || actual.getTargetEnrolledDate() != null || actual.getTargetEnrolledRandomized() != null )){
                        actual.setProtocoloCompromisopais(pcp);
                        actual.setPatientOrder(orden);
                        enrolledPatientsService.attachDirty(actual);
                        orden++;
                }
                else{
                    toRemove.add(index);
                }
            }

            itRemove = toRemove.iterator();
            while(itRemove.hasNext()){
                pcp.getEnrolledPatients().remove(itRemove.next().intValue());
            }

            protocoloCompromisopaisService.save(pcp);
        }
        else{
            globalCommitment.setProtocolo(protocoloRecovered);
            globalCommitmentService.save(globalCommitment);
        }

        cargarTablaYPaises();

        protocoloAEditar = null;
        globalCommitment = null;

        return SUCCESS;
    }

    public Integer getCountryId() {
        return countryId;
    }

    public void setCountryId(Integer countryId) {
        this.countryId = countryId;
    }

    public List<Compromisopais> getPaisList() {
        return paisList;
    }

    public void setPaisList(List<Compromisopais> paisList) {
        this.paisList = paisList;
    }
    public List<ProtocoloCompromisopais> getListaCargados() {
        return listaCargados;
    }

    public void setListaCargados(List<ProtocoloCompromisopais> listaCargados) {
        this.listaCargados = listaCargados;
    }

    public String getEditProtId() {
        return editProtId;
    }

    public void setEditProtId(String editProtId) {
        this.editProtId = editProtId;
    }

    public Integer getEditPaisId() {
        return editPaisId;
    }

    public void setEditPaisId(Integer editPaisId) {
        this.editPaisId = editPaisId;
    }

    public ProtocoloCompromisopais getProtocoloAEditar() {
        return protocoloAEditar;
    }

    public void setProtocoloAEditar(ProtocoloCompromisopais protocoloAEditar) {
        this.protocoloAEditar = protocoloAEditar;
    }

    public GlobalCommitment getGlobalCommitment() {
        return globalCommitment;
    }

    public void setGlobalCommitment(GlobalCommitment globalCommitment) {
        this.globalCommitment = globalCommitment;
    }

    public List<Integer> getYearList() {
        return yearList;
    }

    public void setYearList(List<Integer> yearList) {
        this.yearList = yearList;
    }

    public Integer getEditGlobalId() {
        return editGlobalId;
    }

    public void setEditGlobalId(Integer editGlobalId) {
        this.editGlobalId = editGlobalId;
    }

    public GlobalCommitment getGlobalCommitmentForList() {
        return globalCommitmentForList;
    }

    public void setGlobalCommitmentForList(GlobalCommitment globalCommitmentForList) {
        this.globalCommitmentForList = globalCommitmentForList;
    }

    public EnrolledPatients.EpCategory[] getCategories(){
        return EnrolledPatients.EpCategory.values();
    }
}
